/***************************************************************
 *文件名：  lib_lcd.c
 *作  者：  AE Team
 *版  本：  V1.00
 *日  期：  2023/08/14
 *描  述：  LCD模块库函数
 *备  注：
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ***************************************************************/
#include "lib_scu.h"
#include "lib_lcd.h"

/***************************************************************
  函数名：LCD_Init
  描  述：LCD功能初始化函数
  输入值：LCD_InitStruct 初始化结构体
  输出值：无
  返回值：SUCCESS 成功 ERROR 失败
 ***************************************************************/
ErrorStatus LCD_Init(LCD_InitStruType *LCD_InitStruct)
{
    if (LCD_InitStruct->LCD_DUTY > LCD_COM_DUTY_MAX
            || LCD_InitStruct->LCD_SEG_43_32 > 0xFFF
            || LCD_InitStruct->LCD_QTSEL > LCD_QTSEL_MAX
            || LCD_InitStruct->LCD_VLCD > LCD_VLCD_MAX
            || LCD_InitStruct->LCD_BUFEN > ENABLE
            || LCD_InitStruct->LCD_TYPE > LCD_TYPE_MAX
            || LCD_InitStruct->LCD_CLK > LCD_CLK_MAX
            || LCD_InitStruct->LCD_PRS > LCD_PRS_MAX
            || LCD_InitStruct->LCD_BIAS > LCD_BIAS_MAX
            || LCD_InitStruct->LCD_RS > LCD_RS_MAX
            || LCD_InitStruct->LCD_BLINK > LCD_BLINK_MAX
            || LCD_InitStruct->LCD_FRDIV > 127
		        || LCD_InitStruct->LCD_UPDCTRL > LCD_UPDCTRL_MAX)
        return ERROR;

    SCU_RegUnLock();
    SCU->LCDCLK.CLKSEL = LCD_InitStruct->LCD_CLK;
    SCU->LCDCLK.CLKDIV = LCD_InitStruct->LCD_PRS;
    SCU->LCDCLK.CLKEN = ENABLE;
    SCU_RegLock();

    LCD->MODE.DUTY = LCD_InitStruct->LCD_DUTY;
    LCD->SEGOE0.Word = LCD_InitStruct->LCD_SEG_31_0;
    LCD->SEGOE1.Word = LCD_InitStruct->LCD_SEG_43_32;
    LCD->MODE.QTSEL = LCD_InitStruct->LCD_QTSEL;
    LCD->MODE.VLCD_SEL = LCD_InitStruct ->LCD_VLCD;
    LCD->MODE.BUFEN = LCD_InitStruct->LCD_BUFEN;
    LCD->MODE.TYPE = LCD_InitStruct->LCD_TYPE;
    LCD->MODE.BIAS = LCD_InitStruct->LCD_BIAS;
    LCD->MODE.RSEL = LCD_InitStruct->LCD_RS;
    LCD->CTRL.WSBLINK = LCD_InitStruct->LCD_BLINK;
    LCD->CTRL.FRDIV = LCD_InitStruct->LCD_FRDIV;
		LCD->CTRL.UPDCTRL = LCD_InitStruct->LCD_UPDCTRL;

    LCD_ENABLE();

    return SUCCESS;
}

/***************************************************************
  函数名：LCD_GrayscaleConfig
  描  述：LCD灰度设置（VLCD电压选择）
  输入值：VLCD_Sel 灰度设置值
  输出值：无
  返回值：SUCCESS 成功 ERROR 失败
 ***************************************************************/
ErrorStatus LCD_GrayscaleConfig(uint8_t VLCD_Sel)
{
    if (VLCD_Sel > LCD_VLCD_MAX)
        return ERROR;

    LCD->MODE.VLCD_SEL = VLCD_Sel;

    return SUCCESS;
}

/***************************************************************
  函数名：LCD_FlickerConfig
  描  述：LCD闪烁功能设置
  输入值：BLINK_Mode 闪烁模式
          BLINK_Value 闪烁频率设置值
  输出值：无
  返回值：SUCCESS 成功 ERROR 失败
 ***************************************************************/
ErrorStatus LCD_FlickerConfig(LCD_TYPE_BLINK BLINK_Mode, uint8_t BLINK_Value)
{
    if (BLINK_Mode > LCD_BLINK_MAX || BLINK_Value > 127)
        return ERROR;

		if(BLINK_Mode != LCD_BLINK_OFF)
			  LCD->CTRL.FCVALUE = BLINK_Value;

    LCD->CTRL.WSBLINK = BLINK_Mode;

    return SUCCESS;
}

/***************************************************************
  函数名：LCD_ResistorConfig
  描  述：LCD内部偏压电阻设置
  输入值：Rsel  内部偏压电阻选择
  输出值：无
  返回值：SUCCESS 成功 ERROR 失败
 ***************************************************************/
ErrorStatus LCD_ResistorConfig(LCD_TYPE_RS Rsel)
{
    if (Rsel > LCD_RS_MAX)
        return ERROR;

    LCD->MODE.RSEL = Rsel;

    return SUCCESS;
}

/***************************************************************
  函数名：LCD_SoftUpdate
  描  述：软件生成更新事件
  输入值：无
  输出值：无
  返回值：无
 ***************************************************************/
void LCD_SoftUpdate(void)
{
    LCD->CTRL.SWUPDATE = 1;
}

/***************************************************************
  函数名：LCD_PixelWrite
  描  述：LCD写像素数据
  输入值：bufn     像素寄存器选择
          LCD_data 写入的数据
  输出值：无
  返回值：SUCCESS 成功 ERROR 失败
 ***************************************************************/
ErrorStatus LCD_PixelWrite(uint8_t bufn, uint32_t LCD_data)
{
    if (bufn > 15)
        return ERROR;

    switch (bufn)
    {
        case 0:
            LCD->RAM0.Word = LCD_data;
            break;

        case 1:
            LCD->RAM1.Word = LCD_data;
            break;

        case 2:
            LCD->RAM2.Word = LCD_data;
            break;

        case 3:
            LCD->RAM3.Word = LCD_data;
            break;

        case 4:
            LCD->RAM4.Word = LCD_data;
            break;

        case 5:
            LCD->RAM5.Word = LCD_data;
            break;

        case 6:
            LCD->RAM6.Word = LCD_data;
            break;

        case 7:
            LCD->RAM7.Word = LCD_data;
            break;

        case 8:
            LCD->RAM8.Word = LCD_data;
            break;

        case 9:
            LCD->RAM9.Word = LCD_data;
            break;

        case 10:
            LCD->RAM10.Word = LCD_data;
            break;

        case 11:
            LCD->RAM11.Word = LCD_data;
            break;

        case 12:
            LCD->RAM12.Word = LCD_data;
            break;

        case 13:
            LCD->RAM13.Word = LCD_data;
            break;

        case 14:
            LCD->RAM14.Word = LCD_data;
            break;

        case 15:
            LCD->RAM15.Word = LCD_data;
            break;

        default:
            return ERROR;
    }

    return SUCCESS;
}

/***************************************************************
  函数名：LCD_Reset
  描  述：LCD复位
  输入值：无
  输出值：无
  返回值：无
 ***************************************************************/
void LCD_Reset(void)
{
    SCU_RegUnLock();
    SCU->LCDCLK.CLKSEL = 0;
    SCU->LCDCLK.CLKDIV = 0;
    SCU->LCDCLK.CLKEN = DISABLE;
    SCU_RegLock();

    LCD->MODE.Word = 0x00000000;
    LCD->CTRL.Word = 0x00000000;
    LCD->BLINK1.Word = 0x00000000;
    LCD->BLINK2.Word = 0x00000000;
    LCD->ICR.Word = 0x1;
    LCD->RAM0.Word = 0x00000000;
    LCD->RAM1.Word = 0x00000000;
    LCD->RAM2.Word = 0x00000000;
    LCD->RAM3.Word = 0x00000000;
    LCD->RAM4.Word = 0x00000000;
    LCD->RAM5.Word = 0x00000000;
    LCD->RAM6.Word = 0x00000000;
    LCD->RAM7.Word = 0x00000000;
    LCD->RAM8.Word = 0x00000000;
    LCD->RAM9.Word = 0x00000000;
    LCD->RAM10.Word = 0x00000000;
    LCD->RAM11.Word = 0x00000000;
    LCD->RAM12.Word = 0x00000000;
    LCD->RAM13.Word = 0x00000000;
    LCD->RAM14.Word = 0x00000000;
    LCD->RAM15.Word = 0x00000000;
    LCD->SEGOE0.Word = 0x00000000;
    LCD->SEGOE1.Word = 0x000;
}
